/*
 * Unidata Platform Community Edition
 * Copyright (c) 2013-2020, UNIDATA LLC, All rights reserved.
 * This file is part of the Unidata Platform Community Edition software.
 *
 * Unidata Platform Community Edition is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Unidata Platform Community Edition is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
package org.unidata.mdm.draft.service;

import java.util.List;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.unidata.mdm.draft.context.DraftGetContext;
import org.unidata.mdm.draft.context.DraftPublishContext;
import org.unidata.mdm.draft.context.DraftQueryContext;
import org.unidata.mdm.draft.context.DraftRemoveContext;
import org.unidata.mdm.draft.context.DraftUpsertContext;
import org.unidata.mdm.draft.dto.DraftGetResult;
import org.unidata.mdm.draft.dto.DraftProviderInfo;
import org.unidata.mdm.draft.dto.DraftPublishResult;
import org.unidata.mdm.draft.dto.DraftQueryResult;
import org.unidata.mdm.draft.dto.DraftRemoveResult;
import org.unidata.mdm.draft.dto.DraftUpsertResult;
import org.unidata.mdm.draft.type.DraftProvider;
import org.unidata.mdm.draft.type.Edition;

/**
 * @author Alexander Malyshev
 * Draft service is a service, that allows you to save an object's state
 * and edit this object, without polluting main storage with intermediate versions.
 * Moreover, different users can edit an object simultaneously
 * and even same user can have different drafts for the same object.
 * You can query draft state, see its evolvement, roll back to earlier revisions etc.
 */
public interface DraftService {
    /**
     * Registers a draft provider - a subsystem, that creates draft objects.
     * @param p the provider instance
     * @return true, if successful, false otherwise
     */
    void register(@Nonnull DraftProvider<?> p);
    /**
     * Returns registered provider ids, descriptions and exported tags.
     * @return providers list
     */
    List<DraftProviderInfo> providers();
    /**
     * Loads draft object(s) by supplied criteria.
     * @param ctx the context
     * @return draft object
     */
    DraftGetResult get(DraftGetContext ctx);
    /**
     * Initiates a draft creation or update for a subject.
     * @param ctx the context
     * @return result
     */
    DraftUpsertResult upsert(DraftUpsertContext ctx);
    /**
     * Removes a draft object and all its descendants.
     * @param ctx the context
     * @return true, is successful, false otherwise
     */
    DraftRemoveResult remove(DraftRemoveContext ctx);
    /**
     * Triggers publication process for a draft object.
     * @param ctx the context
     * @return result
     */
    DraftPublishResult publish(DraftPublishContext ctx);
    /**
     * Tells, whether a subject has some drafts, associated with it.
     * @param ctx the context
     * @return true, if has, false otherwise
     */
    boolean hasDraft(DraftQueryContext ctx);
    /**
     * Counts the number of drafts by given criteria.
     * @param ctx the context
     * @return count
     */
    long count(DraftQueryContext ctx);
    /**
     * Returns a number of draft objects by given criteria.
     * @param ctx the context
     * @return collection of draft objects or null on null input
     */
    @Nullable
    DraftQueryResult drafts(DraftQueryContext ctx);
    /**
     * Loads all editions of a draft (the order is from latest to earliest).
     * @param draftId the draft id
     * @param withData true to fetch payload bytes, false otherwise
     * @return collection of editions
     */
    @Nonnull
    List<Edition> editions(long draftId, boolean withData);
    /**
     * Loads current edition of a draft.
     * @param draftId the draft id
     * @param withData true to fetch payload bytes, false otherwise
     * @return edition or null, if the draft doesn't have any editions
     */
    @Nullable
    Edition current(long draftId, boolean withData);
}
